﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

//多态必须满足的两个条件：
//1.必须是基类的指针或引用调用虚函数，因为只有基类的指针或引用才能
//     指向派生类对象
//2.派生类必须对基类的虚函数进行定义的重写/覆盖，这样派生类才有不同的函数
//     多态的不同形态效果才能达到


class Person
{
public:
	//类成员函数前⾯加virtual修饰，那么这个成员函数被称为虚函数。注意⾮成员函数不能加virtual修
	 //饰。
	virtual void OrderTicket() {   //基类的virtual必须要写，否则不构成多态，仅仅是继承。
		cout << "普通人：全价" << endl;
	}
};
class Student :public Person
{
public:
	//虚函数的重写/覆盖：
	//派生类中有一个跟基类完全相同的虚函数（即返回值类型，函数名
	// 参数的类型及个数完全相同，简称三同），称派生类的虚函数重写
	// 了基类的虚函数

	//注意：在重写基类虚函数时，派⽣类的虚函数在不加virtual关键字时，虽然也可以构成重写(因为继承
		//后基类的虚函数被继承下来了在派⽣类依旧保持虚函数属性)，但是该种写法不是很规范，不建议这样
		//使⽤，不过在考试选择题中，经常会故意埋这个坑，让你判断是否构成多态。
	 virtual void OrderTicket() { //派生类的virtual可以不写也能构成多态
		cout << "学生：半价" << endl;
	}
};
class Soldier:public Person
{
public:
	 virtual void OrderTicket() {
		cout << "军人：免费" << endl;
	}
};
void func1(Person* person) { //基类的指针
	person->OrderTicket();
}
void func2(Person& person) { //基类的引用
	person.OrderTicket();
}
int main() {
	Person p;
	Student st;
	Soldier so;
	func1(&p);
	func1(&st);
	func1(&so);
	func2(p);
	func2(st);
	func2(so);

	return 0;
}